#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
详细调试序列LSTM增强模式预测问题
"""

import sys
import os
import torch
from PyQt5.QtWidgets import QApplication

# 添加项目根目录到路径
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)

def detailed_debug_sequence_lstm_prediction():
    """详细调试序列LSTM增强模式预测"""
    print(" 详细调试序列LSTM增强模式预测")
    print("=" * 60)
    
    try:
        from lottery_predictor_app import LotteryPredictorApp
        from algorithms.compatible_plw_lstm import load_compatible_plw_sequence_model
        from algorithms.plw_sequence_lstm import PLWDataProcessor
        
        # 创建应用实例
        if not QApplication.instance():
            app = QApplication(sys.argv)
        
        predictor = LotteryPredictorApp()
        print(" 成功创建LotteryPredictorApp实例")
        
        # 检查模型文件是否存在
        plw_model_path = os.path.join(predictor.base_dir, 'scripts', 'plw', 'plw_sequence_lstm_model.pth')
        print(f"📁 模型文件路径: {plw_model_path}")
        print(f"📁 模型文件是否存在: {os.path.exists(plw_model_path)}")
        
        if os.path.exists(plw_model_path):
            file_size = os.path.getsize(plw_model_path) / (1024 * 1024)
            print(f" 模型文件大小: {file_size:.2f} MB")
            
            # 尝试加载模型
            print("\n🔄 尝试加载模型...")
            try:
                device = torch.device('cpu')  # 强制使用CPU
                plw_model = load_compatible_plw_sequence_model(plw_model_path, device)
                print(" 模型加载成功")
                print(f" 模型设备: {next(plw_model.parameters()).device}")
            except Exception as e:
                print(f" 模型加载失败: {e}")
                import traceback
                print(traceback.format_exc())
                return
        
        # 检查历史数据文件是否存在
        plw_data_file = os.path.join(predictor.base_dir, 'scripts', 'plw', 'plw_history.csv')
        print(f"\n📁 数据文件路径: {plw_data_file}")
        print(f"📁 数据文件是否存在: {os.path.exists(plw_data_file)}")
        
        if os.path.exists(plw_data_file):
            file_size = os.path.getsize(plw_data_file) / 1024
            print(f" 数据文件大小: {file_size:.2f} KB")
            
            # 尝试处理数据
            print("\n🔄 尝试处理数据...")
            try:
                processor = PLWDataProcessor(plw_data_file, window_size=10)
                recent_data = processor.get_recent_data()
                print(f"✅ 数据处理完成")
                print(f" 最近数据形状: {recent_data.shape if recent_data is not None else 'None'}")
                print(f" 最近数据类型: {type(recent_data)}")
                
                if recent_data is not None:
                    print(f" 数据范围: {recent_data.min()} - {recent_data.max()}")
                    print(f" 数据示例: {recent_data}")
            except Exception as e:
                print(f" 数据处理失败: {e}")
                import traceback
                print(traceback.format_exc())
                return
        
        # 尝试完整的预测流程
        print("\n🔄 尝试完整的预测流程...")
        try:
            predictions = []
            num_predictions = 2
            
            if recent_data is not None:
                # 确保数据在正确的设备上
                recent_data = recent_data.to(device)
                
                # 兼容版模型需要完整的10维特征（5个数字特征+5个区域转换特征）
                # recent_data已经包含了完整的10维特征，不需要截取
                input_data = recent_data.float()  # 确保输入是float类型
                
                print(f" 输入数据形状: {input_data.shape}")
                print(f" 输入数据类型: {input_data.dtype}")
                
                # 确保所有数字都在0-9范围内，避免索引超出范围错误
                # 注意：区域转换特征可能包含-1, 0, 1，所以只对数字特征进行裁剪
                input_data_clone = input_data.clone()
                # 对数字特征（偶数索引位置）进行裁剪
                for i in range(0, 10, 2):  # 0, 2, 4, 6, 8 位置是数字特征
                    input_data_clone[:, :, i] = torch.clamp(input_data_clone[:, :, i], 0, 9)
                
                # 使用真实模型预测
                for i in range(num_predictions):
                    with torch.no_grad():
                        # 添加轻微噪声以产生多样性
                        noise_factor = 0.01 + i * 0.005
                        # 只对数字特征添加噪声
                        noisy_input = input_data_clone.clone()
                        for j in range(0, 10, 2):  # 只对数字特征添加噪声
                            noise = torch.randn_like(noisy_input[:, :, j]) * noise_factor
                            noisy_input[:, :, j] = noisy_input[:, :, j] + noise
                        
                        print(f"  第{i+1}次预测输入数据范围: {noisy_input.min()} - {noisy_input.max()}")
                        
                        predictions_tensor, probabilities = plw_model.predict(noisy_input)
                        print(f"  第{i+1}次预测输出类型: {type(predictions_tensor)}")
                        print(f"  第{i+1}次预测输出形状: {predictions_tensor.shape}")
                        
                        predicted_numbers = predictions_tensor[0].cpu().numpy().tolist()
                        print(f"  第{i+1}次预测结果: {predicted_numbers}")
                        
                        predictions.append({
                            'red': predicted_numbers,
                            'blue': [],  # 排列5没有蓝球
                            'confidence': float(torch.max(probabilities[0]).item()) if probabilities is not None else 0.8
                        })
                
                print(f"✅ 预测完成，返回结果数量: {len(predictions)}")
                
                if predictions:
                    for i, pred in enumerate(predictions, 1):
                        print(f"  第{i}组预测: {pred}")
                else:
                    print("⚠️ 预测返回空结果")
            else:
                print("⚠️ 无法获取最近数据")
                
        except Exception as e:
            print(f" 预测过程中发生错误: {e}")
            import traceback
            print(traceback.format_exc())
        
        print("\n✅ 详细调试完成")
        
    except Exception as e:
        print(f" 详细调试失败: {e}")
        import traceback
        print(traceback.format_exc())

if __name__ == "__main__":
    detailed_debug_sequence_lstm_prediction()